home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / tk2.3 / dist / tkCanvWind.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-24  |  21.7 KB  |  773 lines

  1. /* 
  2.  * tkCanvWind.c --
  3.  *
  4.  *    This file implements window items for canvas widgets.
  5.  *
  6.  * Copyright 1992 Regents of the University of California.
  7.  * Permission to use, copy, modify, and distribute this
  8.  * software and its documentation for any purpose and without
  9.  * fee is hereby granted, provided that the above copyright
  10.  * notice appear in all copies.  The University of California
  11.  * makes no representations about the suitability of this
  12.  * software for any purpose.  It is provided "as is" without
  13.  * express or implied warranty.
  14.  */
  15.  
  16. #ifndef lint
  17. static char rcsid[] = "$Header: /user6/ouster/wish/RCS/tkCanvWind.c,v 1.4 92/08/24 09:24:22 ouster Exp $ SPRITE (Berkeley)";
  18. #endif
  19.  
  20. #include <stdio.h>
  21. #include <math.h>
  22. #include "tkInt.h"
  23. #include "tkCanvas.h"
  24.  
  25. /*
  26.  * The structure below defines the record for each window item.
  27.  */
  28.  
  29. typedef struct WindowItem  {
  30.     Tk_Item header;        /* Generic stuff that's the same for all
  31.                  * types.  MUST BE FIRST IN STRUCTURE. */
  32.     double x, y;        /* Coordinates of positioning point for
  33.                  * window. */
  34.     Tk_Window tkwin;        /* Window associated with item.  NULL means
  35.                  * window has been destroyed. */
  36.     int width;            /* Width to use for window (<= 0 means use
  37.                  * window's requested width). */
  38.     int height;            /* Width to use for window (<= 0 means use
  39.                  * window's requested width). */
  40.     Tk_Anchor anchor;        /* Where to anchor window relative to
  41.                  * (x,y). */
  42.     Tk_Canvas *canvasPtr;    /* Canvas containing this item. */
  43. } WindowItem;
  44.  
  45. /*
  46.  * Information used for parsing configuration specs:
  47.  */
  48.  
  49. static Tk_ConfigSpec configSpecs[] = {
  50.     {TK_CONFIG_ANCHOR, "-anchor", (char *) NULL, (char *) NULL,
  51.     "center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT},
  52.     {TK_CONFIG_PIXELS, "-height", (char *) NULL, (char *) NULL,
  53.     "0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT},
  54.     {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL,
  55.     (char *) NULL, 0, TK_CONFIG_NULL_OK, &tkCanvasTagsOption},
  56.     {TK_CONFIG_PIXELS, "-width", (char *) NULL, (char *) NULL,
  57.     "0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT},
  58.     {TK_CONFIG_WINDOW, "-window", (char *) NULL, (char *) NULL,
  59.     (char *) NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK},
  60.     {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
  61.     (char *) NULL, 0, 0}
  62. };
  63.  
  64. /*
  65.  * Prototypes for procedures defined in this file:
  66.  */
  67.  
  68. static void        ComputeWindowBbox _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  69.                 WindowItem *winItemPtr));
  70. static int        ConfigureWinItem _ANSI_ARGS_((
  71.                 Tk_Canvas *canvasPtr, Tk_Item *itemPtr, int argc,
  72.                 char **argv, int flags));
  73. static int        CreateWinItem _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  74.                 struct Tk_Item *itemPtr, int argc, char **argv));
  75. static void        DeleteWinItem _ANSI_ARGS_((Tk_Item *itemPtr));
  76. static void        DisplayWinItem _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  77.                 Tk_Item *itemPtr, Drawable dst));
  78. static void        ScaleWinItem _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  79.                 Tk_Item *itemPtr, double originX, double originY,
  80.                 double scaleX, double scaleY));
  81. static void        TranslateWinItem _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  82.                 Tk_Item *itemPtr, double deltaX, double deltaY));
  83. static int        WinItemCoords _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  84.                 Tk_Item *itemPtr, int argc, char **argv));
  85. static void        WinItemRequestProc _ANSI_ARGS_((ClientData clientData,
  86.                 Tk_Window tkwin));
  87. static void        WinItemStructureProc _ANSI_ARGS_((
  88.                 ClientData clientData, XEvent *eventPtr));
  89. static int        WinItemToArea _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  90.                 Tk_Item *itemPtr, double *rectPtr));
  91. static double        WinItemToPoint _ANSI_ARGS_((Tk_Canvas *canvasPtr,
  92.                 Tk_Item *itemPtr, double *pointPtr));
  93.  
  94. /*
  95.  * The structures below defines the rectangle and oval item types
  96.  * by means of procedures that can be invoked by generic item code.
  97.  */
  98.  
  99. Tk_ItemType TkWindowType = {
  100.     "window",                /* name */
  101.     sizeof(WindowItem),            /* itemSize */
  102.     CreateWinItem,            /* createProc */
  103.     configSpecs,            /* configSpecs */
  104.     ConfigureWinItem,            /* configureProc */
  105.     WinItemCoords,            /* coordProc */
  106.     DeleteWinItem,            /* deleteProc */
  107.     DisplayWinItem,            /* displayProc */
  108.     1,                    /* alwaysRedraw */
  109.     WinItemToPoint,            /* pointProc */
  110.     WinItemToArea,            /* areaProc */
  111.     (Tk_ItemPostscriptProc *) NULL,    /* postscriptProc */
  112.     ScaleWinItem,            /* scaleProc */
  113.     TranslateWinItem,            /* translateProc */
  114.     (Tk_ItemIndexProc *) NULL,        /* indexProc */
  115.     (Tk_ItemCursorProc *) NULL,        /* cursorProc */
  116.     (Tk_ItemSelectionProc *) NULL,    /* selectionProc */
  117.     (Tk_ItemInsertProc *) NULL,        /* insertProc */
  118.     (Tk_ItemDCharsProc *) NULL,        /* dTextProc */
  119.     (Tk_ItemType *) NULL        /* nextPtr */
  120. };
  121.  
  122. /*
  123.  *--------------------------------------------------------------
  124.  *
  125.  * CreateWinItem --
  126.  *
  127.  *    This procedure is invoked to create a new window
  128.  *    item in a canvas.
  129.  *
  130.  * Results:
  131.  *    A standard Tcl return value.  If an error occurred in
  132.  *    creating the item, then an error message is left in
  133.  *    canvasPtr->interp->result;  in this case itemPtr is
  134.  *    left uninitialized, so it can be safely freed by the
  135.  *    caller.
  136.  *
  137.  * Side effects:
  138.  *    A new window item is created.
  139.  *
  140.  *--------------------------------------------------------------
  141.  */
  142.  
  143. static int
  144. CreateWinItem(canvasPtr, itemPtr, argc, argv)
  145.     register Tk_Canvas *canvasPtr;    /* Canvas to hold new item. */
  146.     Tk_Item *itemPtr;            /* Record to hold new item;  header
  147.                      * has been initialized by caller. */
  148.     int argc;                /* Number of arguments in argv. */
  149.     char **argv;            /* Arguments describing rectangle. */
  150. {
  151.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  152.  
  153.     if (argc < 2) {
  154.     Tcl_AppendResult(canvasPtr->interp, "wrong # args:  should be \"",
  155.         Tk_PathName(canvasPtr->tkwin), "\" create ",
  156.         itemPtr->typePtr->name, " x y ?options?",
  157.         (char *) NULL);
  158.     return TCL_ERROR;
  159.     }
  160.  
  161.     /*
  162.      * Initialize item's record.
  163.      */
  164.  
  165.     winItemPtr->tkwin = NULL;
  166.     winItemPtr->width = 0;
  167.     winItemPtr->height = 0;
  168.     winItemPtr->anchor = TK_ANCHOR_CENTER;
  169.     winItemPtr->canvasPtr = canvasPtr;
  170.  
  171.     /*
  172.      * Process the arguments to fill in the item record.
  173.      */
  174.  
  175.     if ((TkGetCanvasCoord(canvasPtr, argv[0], &winItemPtr->x) != TCL_OK)
  176.         || (TkGetCanvasCoord(canvasPtr, argv[1],
  177.         &winItemPtr->y) != TCL_OK)) {
  178.     return TCL_ERROR;
  179.     }
  180.  
  181.     if (ConfigureWinItem(canvasPtr, itemPtr, argc-2, argv+2, 0) != TCL_OK) {
  182.     DeleteWinItem(itemPtr);
  183.     return TCL_ERROR;
  184.     }
  185.     return TCL_OK;
  186. }
  187.  
  188. /*
  189.  *--------------------------------------------------------------
  190.  *
  191.  * WinItemCoords --
  192.  *
  193.  *    This procedure is invoked to process the "coords" widget
  194.  *    command on window items.  See the user documentation for
  195.  *    details on what it does.
  196.  *
  197.  * Results:
  198.  *    Returns TCL_OK or TCL_ERROR, and sets canvasPtr->interp->result.
  199.  *
  200.  * Side effects:
  201.  *    The coordinates for the given item may be changed.
  202.  *
  203.  *--------------------------------------------------------------
  204.  */
  205.  
  206. static int
  207. WinItemCoords(canvasPtr, itemPtr, argc, argv)
  208.     register Tk_Canvas *canvasPtr;    /* Canvas containing item. */
  209.     Tk_Item *itemPtr;            /* Item whose coordinates are to be
  210.                      * read or modified. */
  211.     int argc;                /* Number of coordinates supplied in
  212.                      * argv. */
  213.     char **argv;            /* Array of coordinates: x1, y1,
  214.                      * x2, y2, ... */
  215. {
  216.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  217.  
  218.     if (argc == 0) {
  219.     sprintf(canvasPtr->interp->result, "%g %g", winItemPtr->x,
  220.         winItemPtr->y);
  221.     } else if (argc == 2) {
  222.     if ((TkGetCanvasCoord(canvasPtr, argv[0], &winItemPtr->x) != TCL_OK)
  223.         || (TkGetCanvasCoord(canvasPtr, argv[1],
  224.             &winItemPtr->y) != TCL_OK)) {
  225.         return TCL_ERROR;
  226.     }
  227.     ComputeWindowBbox(canvasPtr, winItemPtr);
  228.     } else {
  229.     sprintf(canvasPtr->interp->result,
  230.         "wrong # coordinates:  expected 0 or 2, got %d",
  231.         argc);
  232.     return TCL_ERROR;
  233.     }
  234.     return TCL_OK;
  235. }
  236.  
  237. /*
  238.  *--------------------------------------------------------------
  239.  *
  240.  * ConfigureWinItem --
  241.  *
  242.  *    This procedure is invoked to configure various aspects
  243.  *    of a window item, such as its anchor position.
  244.  *
  245.  * Results:
  246.  *    A standard Tcl result code.  If an error occurs, then
  247.  *    an error message is left in canvasPtr->interp->result.
  248.  *
  249.  * Side effects:
  250.  *    Configuration information may be set for itemPtr.
  251.  *
  252.  *--------------------------------------------------------------
  253.  */
  254.  
  255. static int
  256. ConfigureWinItem(canvasPtr, itemPtr, argc, argv, flags)
  257.     Tk_Canvas *canvasPtr;    /* Canvas containing itemPtr. */
  258.     Tk_Item *itemPtr;        /* Window item to reconfigure. */
  259.     int argc;            /* Number of elements in argv.  */
  260.     char **argv;        /* Arguments describing things to configure. */
  261.     int flags;            /* Flags to pass to Tk_ConfigureWidget. */
  262. {
  263.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  264.     Tk_Window oldWindow;
  265.  
  266.     oldWindow = winItemPtr->tkwin;
  267.     if (Tk_ConfigureWidget(canvasPtr->interp, canvasPtr->tkwin,
  268.         configSpecs, argc, argv, (char *) winItemPtr, flags) != TCL_OK) {
  269.     return TCL_ERROR;
  270.     }
  271.  
  272.     /*
  273.      * A few of the options require additional processing.
  274.      */
  275.  
  276.     if (oldWindow != winItemPtr->tkwin) {
  277.     if (oldWindow != NULL) {
  278.         Tk_DeleteEventHandler(oldWindow, StructureNotifyMask,
  279.             WinItemStructureProc, (ClientData) winItemPtr);
  280.         Tk_ManageGeometry(oldWindow, (Tk_GeometryProc *) NULL,
  281.             (ClientData) NULL);
  282.         Tk_UnmapWindow(oldWindow);
  283.     }
  284.     if (winItemPtr->tkwin != NULL) {
  285.         Tk_Window ancestor, parent;
  286.  
  287.         /*
  288.          * Make sure that the canvas is either the parent of the
  289.          * window associated with the item or a descendant of that
  290.          * parent.  Also, don't allow a top-level window to be
  291.          * managed inside a canvas.
  292.          */
  293.  
  294.         parent = Tk_Parent(winItemPtr->tkwin);
  295.         for (ancestor = canvasPtr->tkwin; ;
  296.             ancestor = Tk_Parent(ancestor)) {
  297.         if (ancestor == parent) {
  298.             break;
  299.         }
  300.         if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_LEVEL) {
  301.             badWindow:
  302.             Tcl_AppendResult(canvasPtr->interp, "can't use ",
  303.                 Tk_PathName(winItemPtr->tkwin),
  304.                 " in a window item of this canvas", (char *) NULL);
  305.             winItemPtr->tkwin = NULL;
  306.             return TCL_ERROR;
  307.         }
  308.         }
  309.         if (((Tk_FakeWin *) (winItemPtr->tkwin))->flags & TK_TOP_LEVEL) {
  310.         goto badWindow;
  311.         }
  312.         if (winItemPtr->tkwin == canvasPtr->tkwin) {
  313.         goto badWindow;
  314.         }
  315.         Tk_CreateEventHandler(winItemPtr->tkwin, StructureNotifyMask,
  316.             WinItemStructureProc, (ClientData) winItemPtr);
  317.         Tk_ManageGeometry(winItemPtr->tkwin, WinItemRequestProc,
  318.             (ClientData) winItemPtr);
  319.     }
  320.     }
  321.  
  322.     ComputeWindowBbox(canvasPtr, winItemPtr);
  323.  
  324.     return TCL_OK;
  325. }
  326.  
  327. /*
  328.  *--------------------------------------------------------------
  329.  *
  330.  * DeleteWinItem --
  331.  *
  332.  *    This procedure is called to clean up the data structure
  333.  *    associated with a window item.
  334.  *
  335.  * Results:
  336.  *    None.
  337.  *
  338.  * Side effects:
  339.  *    Resources associated with itemPtr are released.
  340.  *
  341.  *--------------------------------------------------------------
  342.  */
  343.  
  344. static void
  345. DeleteWinItem(itemPtr)
  346.     Tk_Item *itemPtr;            /* Item that is being deleted. */
  347. {
  348.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  349.  
  350.     if (winItemPtr->tkwin != NULL) {
  351.     Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
  352.         WinItemStructureProc, (ClientData) winItemPtr);
  353.     Tk_ManageGeometry(winItemPtr->tkwin, (Tk_GeometryProc *) NULL,
  354.         (ClientData) NULL);
  355.     Tk_UnmapWindow(winItemPtr->tkwin);
  356.     }
  357. }
  358.  
  359. /*
  360.  *--------------------------------------------------------------
  361.  *
  362.  * ComputeWindowBbox --
  363.  *
  364.  *    This procedure is invoked to compute the bounding box of
  365.  *    all the pixels that may be drawn as part of a window item.
  366.  *    This procedure is where the child window's placement is
  367.  *    computed.
  368.  *
  369.  * Results:
  370.  *    None.
  371.  *
  372.  * Side effects:
  373.  *    The fields x1, y1, x2, and y2 are updated in the header
  374.  *    for itemPtr.
  375.  *
  376.  *--------------------------------------------------------------
  377.  */
  378.  
  379.     /* ARGSUSED */
  380. static void
  381. ComputeWindowBbox(canvasPtr, winItemPtr)
  382.     Tk_Canvas *canvasPtr;        /* Canvas that contains item. */
  383.     register WindowItem *winItemPtr;    /* Item whose bbox is to be
  384.                      * recomputed. */
  385. {
  386.     int width, height, x, y;
  387.  
  388.     x = winItemPtr->x + 0.5;
  389.     y = winItemPtr->y + 0.5;
  390.  
  391.     if (winItemPtr->tkwin == NULL) {
  392.     winItemPtr->header.x1 = winItemPtr->header.x2 = x;
  393.     winItemPtr->header.y1 = winItemPtr->header.y2 = y;
  394.     return;
  395.     }
  396.  
  397.     /*
  398.      * Compute dimensions of window.
  399.      */
  400.  
  401.     width = winItemPtr->width;
  402.     if (width <= 0) {
  403.     width = Tk_ReqWidth(winItemPtr->tkwin);
  404.     if (width <= 0) {
  405.         width = 1;
  406.     }
  407.     }
  408.     height = winItemPtr->height;
  409.     if (height <= 0) {
  410.     height = Tk_ReqHeight(winItemPtr->tkwin);
  411.     if (height <= 0) {
  412.         height = 1;
  413.     }
  414.     }
  415.  
  416.     /*
  417.      * Compute location of window, using anchor information.
  418.      */
  419.  
  420.     switch (winItemPtr->anchor) {
  421.     case TK_ANCHOR_N:
  422.         x -= width/2;
  423.         break;
  424.     case TK_ANCHOR_NE:
  425.         x -= width;
  426.         break;
  427.     case TK_ANCHOR_E:
  428.         x -= width;
  429.         y -= height/2;
  430.         break;
  431.     case TK_ANCHOR_SE:
  432.         x -= width;
  433.         y -= height;
  434.         break;
  435.     case TK_ANCHOR_S:
  436.         x -= width/2;
  437.         y -= height;
  438.         break;
  439.     case TK_ANCHOR_SW:
  440.         y -= height;
  441.         break;
  442.     case TK_ANCHOR_W:
  443.         y -= height/2;
  444.         break;
  445.     case TK_ANCHOR_NW:
  446.         break;
  447.     case TK_ANCHOR_CENTER:
  448.         x -= width/2;
  449.         y -= height/2;
  450.         break;
  451.     }
  452.  
  453.     /*
  454.      * Store the information in the item header.
  455.      */
  456.  
  457.     winItemPtr->header.x1 = x;
  458.     winItemPtr->header.y1 = y;
  459.     winItemPtr->header.x2 = x + width;
  460.     winItemPtr->header.y2 = y + height;
  461. }
  462.  
  463. /*
  464.  *--------------------------------------------------------------
  465.  *
  466.  * DisplayWinItem --
  467.  *
  468.  *    This procedure is invoked to "draw" a window item in a given
  469.  *    drawable.  Since the window draws itself, we needn't do any
  470.  *    actual redisplay here.  However, this procedure takes care
  471.  *    of actually repositioning the child window so that it occupies
  472.  *    the correct screen position.
  473.  *
  474.  * Results:
  475.  *    None.
  476.  *
  477.  * Side effects:
  478.  *    The child window's position may get changed.
  479.  *
  480.  *--------------------------------------------------------------
  481.  */
  482.  
  483.     /* ARGSUSED */
  484. static void
  485. DisplayWinItem(canvasPtr, itemPtr, drawable)
  486.     register Tk_Canvas *canvasPtr;    /* Canvas that contains item. */
  487.     Tk_Item *itemPtr;            /* Item to be displayed. */
  488.     Drawable drawable;            /* Pixmap or window in which to draw
  489.                      * item. */
  490. {
  491.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  492.     int x,y, width, height;
  493.     Tk_Window ancestor, parent;
  494.  
  495.     if (winItemPtr->tkwin == NULL) {
  496.     return;
  497.     }
  498.     x = winItemPtr->header.x1 - canvasPtr->xOrigin;
  499.     y = winItemPtr->header.y1 - canvasPtr->yOrigin;
  500.     width = winItemPtr->header.x2 - winItemPtr->header.x1;
  501.     height = winItemPtr->header.y2 - winItemPtr->header.y1;
  502.  
  503.     /*
  504.      * If the canvas isn't the parent of the window, then translate the
  505.      * coordinates from those of the canvas to those of the window's
  506.      * parent.
  507.      */
  508.  
  509.     parent = Tk_Parent(winItemPtr->tkwin);
  510.     for (ancestor = canvasPtr->tkwin; ancestor != parent;
  511.         ancestor = Tk_Parent(ancestor)) {
  512.     x += Tk_X(ancestor) + Tk_Changes(ancestor)->border_width;
  513.     y += Tk_Y(ancestor) + Tk_Changes(ancestor)->border_width;
  514.     }
  515.  
  516.     /*
  517.      * Reconfigure the window if it isn't already in the correct place.
  518.      */
  519.  
  520.     if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))
  521.         || (width != Tk_Width(winItemPtr->tkwin))
  522.         || (height != Tk_Height(winItemPtr->tkwin))) {
  523.     Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, (unsigned int) width,
  524.         (unsigned int) height);
  525.     }
  526.     if (!Tk_IsMapped(winItemPtr->tkwin)) {
  527.     Tk_MapWindow(winItemPtr->tkwin);
  528.     }
  529. }
  530.  
  531. /*
  532.  *--------------------------------------------------------------
  533.  *
  534.  * WinItemToPoint --
  535.  *
  536.  *    Computes the distance from a given point to a given
  537.  *    rectangle, in canvas units.
  538.  *
  539.  * Results:
  540.  *    The return value is 0 if the point whose x and y coordinates
  541.  *    are coordPtr[0] and coordPtr[1] is inside the window.  If the
  542.  *    point isn't inside the window then the return value is the
  543.  *    distance from the point to the window.
  544.  *
  545.  * Side effects:
  546.  *    None.
  547.  *
  548.  *--------------------------------------------------------------
  549.  */
  550.  
  551.     /* ARGSUSED */
  552. static double
  553. WinItemToPoint(canvasPtr, itemPtr, pointPtr)
  554.     Tk_Canvas *canvasPtr;    /* Canvas containing item. */
  555.     Tk_Item *itemPtr;        /* Item to check against point. */
  556.     double *pointPtr;        /* Pointer to x and y coordinates. */
  557. {
  558.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  559.     double x1, x2, y1, y2, xDiff, yDiff;
  560.  
  561.     x1 = winItemPtr->header.x1;
  562.     y1 = winItemPtr->header.y1;
  563.     x2 = winItemPtr->header.x2;
  564.     y2 = winItemPtr->header.y2;
  565.  
  566.     /*
  567.      * Point is outside rectangle.
  568.      */
  569.  
  570.     if (pointPtr[0] < x1) {
  571.     xDiff = x1 - pointPtr[0];
  572.     } else if (pointPtr[0] > x2)  {
  573.     xDiff = pointPtr[0] - x2;
  574.     } else {
  575.     xDiff = 0;
  576.     }
  577.  
  578.     if (pointPtr[1] < y1) {
  579.     yDiff = y1 - pointPtr[1];
  580.     } else if (pointPtr[1] > y2)  {
  581.     yDiff = pointPtr[1] - y2;
  582.     } else {
  583.     yDiff = 0;
  584.     }
  585.  
  586.     return hypot(xDiff, yDiff);
  587. }
  588.  
  589. /*
  590.  *--------------------------------------------------------------
  591.  *
  592.  * WinItemToArea --
  593.  *
  594.  *    This procedure is called to determine whether an item
  595.  *    lies entirely inside, entirely outside, or overlapping
  596.  *    a given rectangle.
  597.  *
  598.  * Results:
  599.  *    -1 is returned if the item is entirely outside the area
  600.  *    given by rectPtr, 0 if it overlaps, and 1 if it is entirely
  601.  *    inside the given area.
  602.  *
  603.  * Side effects:
  604.  *    None.
  605.  *
  606.  *--------------------------------------------------------------
  607.  */
  608.  
  609.     /* ARGSUSED */
  610. static int
  611. WinItemToArea(canvasPtr, itemPtr, rectPtr)
  612.     Tk_Canvas *canvasPtr;    /* Canvas containing item. */
  613.     Tk_Item *itemPtr;        /* Item to check against rectangle. */
  614.     double *rectPtr;        /* Pointer to array of four coordinates
  615.                  * (x1, y1, x2, y2) describing rectangular
  616.                  * area.  */
  617. {
  618.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  619.  
  620.     if ((rectPtr[2] <= winItemPtr->header.x1)
  621.         || (rectPtr[0] >= winItemPtr->header.x2)
  622.         || (rectPtr[3] <= winItemPtr->header.y1)
  623.         || (rectPtr[1] >= winItemPtr->header.y2)) {
  624.     return -1;
  625.     }
  626.     if ((rectPtr[0] <= winItemPtr->header.x1)
  627.         && (rectPtr[1] <= winItemPtr->header.y1)
  628.         && (rectPtr[2] >= winItemPtr->header.x2)
  629.         && (rectPtr[3] >= winItemPtr->header.y2)) {
  630.     return 1;
  631.     }
  632.     return 0;
  633. }
  634.  
  635. /*
  636.  *--------------------------------------------------------------
  637.  *
  638.  * ScaleWinItem --
  639.  *
  640.  *    This procedure is invoked to rescale a rectangle or oval
  641.  *    item.
  642.  *
  643.  * Results:
  644.  *    None.
  645.  *
  646.  * Side effects:
  647.  *    The rectangle or oval referred to by itemPtr is rescaled
  648.  *    so that the following transformation is applied to all
  649.  *    point coordinates:
  650.  *        x' = originX + scaleX*(x-originX)
  651.  *        y' = originY + scaleY*(y-originY)
  652.  *
  653.  *--------------------------------------------------------------
  654.  */
  655.  
  656. static void
  657. ScaleWinItem(canvasPtr, itemPtr, originX, originY, scaleX, scaleY)
  658.     Tk_Canvas *canvasPtr;        /* Canvas containing rectangle. */
  659.     Tk_Item *itemPtr;            /* Rectangle to be scaled. */
  660.     double originX, originY;        /* Origin about which to scale rect. */
  661.     double scaleX;            /* Amount to scale in X direction. */
  662.     double scaleY;            /* Amount to scale in Y direction. */
  663. {
  664.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  665.  
  666.     winItemPtr->x = originX + scaleX*(winItemPtr->x - originX);
  667.     winItemPtr->y = originY + scaleY*(winItemPtr->y - originY);
  668.     if (winItemPtr->width > 0) {
  669.     winItemPtr->width = scaleY*winItemPtr->width;
  670.     }
  671.     if (winItemPtr->height > 0) {
  672.     winItemPtr->height = scaleY*winItemPtr->height;
  673.     }
  674.     ComputeWindowBbox(canvasPtr, winItemPtr);
  675. }
  676.  
  677. /*
  678.  *--------------------------------------------------------------
  679.  *
  680.  * TranslateWinItem --
  681.  *
  682.  *    This procedure is called to move a rectangle or oval by a
  683.  *    given amount.
  684.  *
  685.  * Results:
  686.  *    None.
  687.  *
  688.  * Side effects:
  689.  *    The position of the rectangle or oval is offset by
  690.  *    (xDelta, yDelta), and the bounding box is updated in the
  691.  *    generic part of the item structure.
  692.  *
  693.  *--------------------------------------------------------------
  694.  */
  695.  
  696. static void
  697. TranslateWinItem(canvasPtr, itemPtr, deltaX, deltaY)
  698.     Tk_Canvas *canvasPtr;        /* Canvas containing item. */
  699.     Tk_Item *itemPtr;            /* Item that is being moved. */
  700.     double deltaX, deltaY;        /* Amount by which item is to be
  701.                      * moved. */
  702. {
  703.     register WindowItem *winItemPtr = (WindowItem *) itemPtr;
  704.  
  705.     winItemPtr->x += deltaX;
  706.     winItemPtr->y += deltaY;
  707.     ComputeWindowBbox(canvasPtr, winItemPtr);
  708. }
  709.  
  710. /*
  711.  *--------------------------------------------------------------
  712.  *
  713.  * WinItemStructureProc --
  714.  *
  715.  *    This procedure is invoked whenever StructureNotify events
  716.  *    occur for a window that's managed as part of a canvas window
  717.  *    item.  This procudure's only purpose is to clean up when
  718.  *    windows are deleted.
  719.  *
  720.  * Results:
  721.  *    None.
  722.  *
  723.  * Side effects:
  724.  *    The window is disassociated from the window item when it is
  725.  *    deleted.
  726.  *
  727.  *--------------------------------------------------------------
  728.  */
  729.  
  730. static void
  731. WinItemStructureProc(clientData, eventPtr)
  732.     ClientData clientData;    /* Pointer to record describing window item. */
  733.     XEvent *eventPtr;        /* Describes what just happened. */
  734. {
  735.     register WindowItem *winItemPtr = (WindowItem *) clientData;
  736.  
  737.     if (eventPtr->type == DestroyNotify) {
  738.     winItemPtr->tkwin = NULL;
  739.     }
  740. }
  741.  
  742. /*
  743.  *--------------------------------------------------------------
  744.  *
  745.  * WinItemRequestProc --
  746.  *
  747.  *    This procedure is invoked whenever a window that's associated
  748.  *    with a window canvas item changes its requested dimensions.
  749.  *
  750.  * Results:
  751.  *    None.
  752.  *
  753.  * Side effects:
  754.  *    The size and location on the screen of the window may change,
  755.  *    depending on the options specified for the window item.
  756.  *
  757.  *--------------------------------------------------------------
  758.  */
  759.  
  760.     /* ARGSUSED */
  761. static void
  762. WinItemRequestProc(clientData, tkwin)
  763.     ClientData clientData;        /* Pointer to record for window item. */
  764.     Tk_Window tkwin;            /* Window that changed its desired
  765.                      * size. */
  766. {
  767.     WindowItem *winItemPtr = (WindowItem *) clientData;
  768.  
  769.     ComputeWindowBbox(winItemPtr->canvasPtr, winItemPtr);
  770.     DisplayWinItem(winItemPtr->canvasPtr, (Tk_Item *) winItemPtr,
  771.         (Drawable) None);
  772. }
  773.